package com.yami.shop.mystery.common.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.event.EsMysteryBoxUpdateEvent;
import com.yami.shop.bean.event.SubmitOrderEvent;
import com.yami.shop.bean.event.SubmitOrderQualificationEvent;
import com.yami.shop.bean.event.TryLockStockEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.dao.OrderMapper;
import com.yami.shop.dao.PayInfoMapper;
import com.yami.shop.mystery.common.dao.MysteryBoxOrderMapper;
import com.yami.shop.mystery.common.dao.MysteryBoxSkuMapper;
import com.yami.shop.mystery.common.model.MysteryBoxOrder;
import com.yami.shop.mystery.common.service.ActivityPresellService;
import com.yami.shop.mystery.common.service.MysteryBoxOrderService;
import com.yami.shop.mystery.common.service.MysteryBoxService;
import com.yami.shop.service.OrderItemService;
import com.yami.shop.service.OrderService;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 盲盒盒子订单业务实现类
 *
 * @author wxf
 * @date 2023/4/13 9:30
 */
@Service
@AllArgsConstructor
public class MysteryBoxOrderServiceImpl extends ServiceImpl<MysteryBoxOrderMapper, MysteryBoxOrder> implements MysteryBoxOrderService {

    private final MysteryBoxOrderMapper mysteryBoxOrderMapper;

    private final MysteryBoxService mysteryBoxService;

    private final OrderService orderService;

    private final ActivityPresellService activityPresellService;

    private final MysteryBoxSkuMapper mysteryBoxSkuMapper;

    private final PayInfoMapper payInfoMapper;

    private final ApplicationEventPublisher eventPublisher;

    private final OrderMapper orderMapper;

    private final OrderItemService orderItemService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Order> submit(ShopCartOrderMergerDto mergerOrder) {

        String userId = mergerOrder.getUserId();
        // 扣减商品库存，本次下单使用的优惠券、积分
        TryLockStockEvent tryLockStockEvent = new TryLockStockEvent(mergerOrder, userId);
        eventPublisher.publishEvent(tryLockStockEvent);
        mergerOrder.setProdList(tryLockStockEvent.getProdList());
        List<Order> orderList = new ArrayList<>();

        // 提交订单
        eventPublisher.publishEvent(new SubmitOrderEvent(mergerOrder, orderList));
        List<OrderItem> orderItems = orderList.stream().flatMap(order -> order.getOrderItems().stream()).collect(Collectors.toList());
        // 预售活动下获取优先购资格ID
        if (Objects.equals(mergerOrder.getOrderType(), OrderType.PRESELL)) {
            eventPublisher.publishEvent(new SubmitOrderQualificationEvent(mergerOrder, orderItems, 3));
        }

        // 插入订单
        orderService.saveBatch(orderList);

        // 插入订单项，返回主键
        orderItemService.insertBatchOrderItem(orderItems);

        return orderList;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelUnpayOrderByOrderNumber(String orderNumber) {

        MysteryBoxOrder seckillOrder = mysteryBoxOrderMapper.selectOne(Wrappers.lambdaQuery(MysteryBoxOrder.class)
                .eq(MysteryBoxOrder::getOrderNumber, orderNumber));
        if (Objects.isNull(seckillOrder)) {
            return;
        }
        // 还原盲盒库存
        mysteryBoxSkuMapper.returnStocksByOrderNumber(orderNumber);
        // 盲盒订单修改为失效
        mysteryBoxOrderMapper.cancelUnpayOrderByOrderNumber(orderNumber);
        // 清除库存的缓存
        RedisUtil.del(Constant.MYSTERY_BOX_SKU_STOCKS_PREFIX + seckillOrder.getMysteryBoxId());
        eventPublisher.publishEvent(new EsMysteryBoxUpdateEvent(seckillOrder.getMysteryBoxId(), null, EsOperationType.UPDATE));
    }

    @Override
//    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<?> lock(List<MysteryBoxOrder> skuStockLocksParam, List<Order> orders) {

        for (MysteryBoxOrder mysteryBoxOrder : skuStockLocksParam) {
            mysteryBoxOrder.setCreateTime(new Date());
            // 盲盒成功等待支付
            mysteryBoxOrder.setState(0);
            // 减sku库存
            Boolean skuStats = mysteryBoxService.decrMysteryBoxSkuStocks(mysteryBoxOrder.getMysteryBoxId(), mysteryBoxOrder.getProdCount().intValue());
            if (!skuStats) {
                return ServerResponseEntity.fail(ResponseEnum.NOT_STOCK, mysteryBoxOrder.getMysteryBoxSkuId());
            }
            // 保存库存锁定信息
            mysteryBoxOrderMapper.insert(mysteryBoxOrder);
        }

        return ServerResponseEntity.success();
    }

}
